<script lang="ts" setup name="Roles">
import { onMounted, ref, reactive } from 'vue';
import { Plus, Upload, Download, Delete } from '@element-plus/icons-vue'
import { fetchRolesPageApi, createRoleApi, deleteRoleByIdApi, updateRoleApi, batchDeleteRolesApi, fetchMenusOfRoleApi, assignMenusApi } from '@/api/system/roles/index'
import { fetchMenusTreeApi } from '@/api/system/menus/index'
import { ElTree, FormInstance } from 'element-plus';
import { resetForm } from '@/utils/common'
import { Role } from '@/api/system/roles/type'

const multipleSelection = ref<string[]>([])
const handleSelectionChange = (roles: Role[]) => {
    multipleSelection.value = roles.map(role => role.id)
}
const current = ref(1)
const size = ref(10)
// 角色表格数据
const tableData = ref<Role[]>([
    { id: '1', name: 'test role', title: '测试角色', disabled: true, remark: '角色备注' }
])

const handleSizeChange = (val: number) => {
    size.value = val
    fetchRolesList()
}
const handleCurrentChange = (val: number) => {
    current.value = val
    fetchRolesList()
}
// 查询表单
const queryFormRef = ref<FormInstance>()
const queryForm = reactive({
    name: '',
    title: '',
    disabled: '',
})
const resetQueryForm = () => {
    resetForm(queryFormRef.value)
    current.value = 1
    fetchRolesList()
}

// 获取角色列表
const fetchRolesList = async () => {
    const res = await fetchRolesPageApi(current.value, size.value, queryForm)
    tableData.value = res.data.data.records
}

// 抽屉
const drawerFormRef = ref<FormInstance>()
const drawer = reactive({
    visible: false,
    mode: ''
})
const role = ref<Role>({
    id: '',
    name: '',
    disabled: false,
    remark: '',
    title: ''
})
// 添加/编辑页面关闭之前处理
const handleClose = (done: () => void) => {
    resetForm(drawerFormRef.value)
    done()
}
// 
// 添加按钮点击事件
const addClick = () => {
    drawer.visible = true
    drawer.mode = 'add'
}
// 编辑按钮点击事件
const editClick = (rowData: any) => {
    drawer.visible = true
    drawer.mode = 'update'
    nextTick(() => {
        role.value = { ...rowData }
    })
}
// 添加/编辑事件提交
const submit = async () => {
    try {
        if (drawer.mode == 'add') {
            await createRoleApi(role.value)
        } else if (drawer.mode == 'update') {
            await updateRoleApi(role.value)
        }
        drawer.visible = false
        resetForm(drawerFormRef.value)
        current.value = 1
        fetchRolesList()
        ElMessage({
            message: '提交成功',
            type: 'success',
            plain: true,
        })
    } catch (err) {
        ElMessage({
            message: '提交失败',
            type: 'error',
            plain: true,
        })
    }
}
// 删除单个菜单
const deleteClick = (id: string) => {
    try {
        deleteRoleByIdApi(id)
        current.value = 1
        fetchRolesList()
        ElMessage({
            message: '删除成功',
            type: 'success',
            plain: true,
        })
    } catch (err) {
        ElMessage({
            message: '删除失败',
            type: 'error',
            plain: true,
        })
    }
}

// 批量删除
const deleteBatchClick = async () => {
    try {
        await batchDeleteRolesApi(multipleSelection.value)
        fetchRolesList()
        ElMessage({
            message: '删除成功',
            type: 'success',
            plain: true,
        })
    } catch (err) {
        ElMessage({
            message: '删除失败',
            type: 'error',
            plain: true,
        })
    }
}

const dialog = reactive({
    visible: false,
    roleId: '',
    roleName: '',
})
const menuTreeRef = ref<InstanceType<typeof ElTree>>()
// 所有角色列表
const menuTree = ref([])
// 已勾选的角色列表
const selectedMenuIds = ref<string[]>([])
// 清空对话框内容
const clearDialogContent = () => {
    dialog.roleId = ''
    menuTreeRef.value!.setCheckedKeys([], false)
    dialog.roleName = ''
}

const dialogClose = (done: () => void) => {
    clearDialogContent()
    done()
}

const assignMeusClick = async (rowData: Role) => {
    try {
        dialog.visible = true
        dialog.roleId = rowData.id
        dialog.roleName = rowData.name
        const res = await fetchMenusOfRoleApi(rowData.id)
        nextTick(() => {
            selectedMenuIds.value = res.data.data.map((menu: { id: string; }) => menu.id)
        })
    } catch (err) {
        ElMessage({
            message: '获取用户的角色信息失败',
            type: 'error',
            plain: true,
        })
    }
}
const assignMenusSubmit = async () => {
    try {
        const menuIds = menuTreeRef.value!.getCheckedKeys(false)
        await assignMenusApi(dialog.roleId, menuIds)
        dialog.visible = false
        clearDialogContent()
    } catch (err) {
        ElMessage({
            message: '分配角色失败',
            type: 'error',
            plain: true,
        })
    }
}

const fetchMenusTree = async () => {
    try {
        const res = await fetchMenusTreeApi({ name: '' })
        menuTree.value = res.data.data
    } catch (err) {
        ElMessage({
            message: '获取角色列表数据出错',
            type: 'error',
            plain: true,
        })
    }
}

onMounted(() => {
    fetchRolesList()
    fetchMenusTree()
})
</script>

<template>
    <div h-full flex flex-col gap-row-4 box-border w-full>
        <div style="box-shadow: var(--el-box-shadow);" w-full box-border>
            <el-form :inline="true" :model="queryForm" style="margin: 1rem 1rem 0 1rem" ref="queryFormRef">
                <el-form-item label="名称" prop="name">
                    <el-input v-model="queryForm.name" placeholder="请输入名称" clearable />
                </el-form-item>
                <el-form-item label="标题" prop="title">
                    <el-input v-model="queryForm.title" placeholder="请输入标题" clearable />
                </el-form-item>
                <el-form-item label="状态" prop="disabled">
                    <el-select v-model="queryForm.disabled" placeholder="请选择状态" clearable style="width: 10rem;"
                        :empty-values="[null, undefined]">
                        <el-option label="All" value="" />
                        <el-option label="启用" :value="false" />
                        <el-option label="禁用" :value="true" />
                    </el-select>
                </el-form-item>
                <el-form-item>
                    <el-button @click="fetchRolesList">查询</el-button>
                    <el-button @click="resetQueryForm">重置</el-button>
                </el-form-item>
            </el-form>
        </div>
        <div flex-1 overflow-hidden box-border position-relative pt-2 style="box-shadow: var(--el-box-shadow);">
            <div flex flex-col overflow-hidden box-border position-absolute w-full h-full>
                <div flex flex-justify-end p-4>
                    <ElButton :icon="Plus" circle @click="addClick"></ElButton>
                    <ElButton :icon="Upload" circle></ElButton>
                    <ElButton :icon="Download" circle></ElButton>
                    <ElButton :icon="Delete" circle @click="deleteBatchClick" </ElButton>
                </div>
                <div flex-1 overflow-hidden box-border>
                    <ElTable :data="tableData" w-full box-border :border="true" height="100%"
                        @selection-change="handleSelectionChange" :cell-style="{ 'text-align': 'center' }"
                        :header-cell-style="{ 'text-align': 'center' }">
                        <el-table-column type="selection" width="55" />
                        <el-table-column fixed prop="name" label="名称" width="150" />
                        <el-table-column prop="title" label="标题" width="120" />
                        <el-table-column prop="status" label="状态" width="120">
                            <template #default="scope">
                                <ElTag :type="scope.row.disabled ? 'danger' : 'success'">
                                    {{ scope.row.disabled ? '禁用' : '启用' }}
                                </ElTag>
                            </template>
                        </el-table-column>
                        <el-table-column prop="remark" label="简介" />
                        <el-table-column fixed="right" label="操作" width="120">
                            <template #default="scope">
                                <div flex flex-justify-around flex-items-center>
                                    <el-tooltip effect="dark" content="编辑">
                                        <ElIcon @click="editClick(scope.row)">
                                            <i i-ep-edit />
                                        </ElIcon>
                                    </el-tooltip>
                                    <el-tooltip effect="dark" content="分配菜单">
                                        <ElIcon @click="assignMeusClick(scope.row)">
                                            <i i-tdesign-menu />
                                        </ElIcon>
                                    </el-tooltip>
                                    <el-tooltip effect="dark" content="删除">
                                        <div flex>
                                            <el-popconfirm title="你确认删除该条记录?" confirm-button-text="确认"
                                                cancel-button-text="取消">
                                                <template #reference>
                                                    <ElIcon @click="deleteClick(scope.row.id)">
                                                        <i i-ep-delete />
                                                    </ElIcon>
                                                </template>
                                            </el-popconfirm>
                                        </div>
                                    </el-tooltip>
                                </div>
                            </template>
                        </el-table-column>
                    </ElTable>
                </div>

                <div style="box-shadow: var(--el-box-shadow);" >
                    <ElPagination v-model:current-page="current" v-model:page-size="size" :page-sizes="[5, 10, 20, 50]"
                        layout="sizes,->,prev, pager, next" @size-change="handleSizeChange"
                        @current-change="handleCurrentChange" />
                </div>
            </div>
        </div>

        <!-- 新增/修改抽屉组件 -->
        <el-drawer v-model="drawer.visible" :title="drawer.mode == 'add' ? '新增' : (drawer.mode == 'update' ? '修改' : '')"
            direction="rtl" :before-close="handleClose">
            <el-form :model="role" label-width="auto" ref="drawerFormRef">
                <el-form-item label="名称" prop="name">
                    <el-input v-model="role.name" />
                </el-form-item>
                <el-form-item label="标题" prop="title">
                    <el-input v-model="role.title" />
                </el-form-item>
                <el-form-item label="备注" prop="title">
                    <el-input v-model="role.remark" />
                </el-form-item>
                <el-form-item label="是否启用" prop="title">
                    <el-switch v-model="role.disabled" active-text="禁用" inactive-text="启用" inline-prompt
                        style="--el-switch-on-color: #ff4949; --el-switch-off-color: #13ce66" />
                </el-form-item>
            </el-form>
            <template #footer>
                <ElDivider />
                <ElButton size="large" @click="submit">提交</ElButton>
            </template>
        </el-drawer>

        <!-- 分配菜单 -->
        <el-dialog v-model="dialog.visible" title="分配菜单" width="500" :before-close="dialogClose"
            :close-on-click-modal="false">
            <div flex flex-items-center>
                <span flex-shrink-0 mr-4>角色</span>
                <el-input v-model="dialog.roleName" disabled />
            </div>
            <div my-4>菜单列表</div>
            <el-tree style="max-width: 600px" :data="menuTree" show-checkbox node-key="id"
                :default-checked-keys="selectedMenuIds" :props="{ label: 'name', children: 'children' }"
                ref="menuTreeRef" />
            <template #footer>
                <div class="dialog-footer">
                    <el-button @click="dialog.visible = false; clearDialogContent();">取消</el-button>
                    <el-button type="primary" @click="assignMenusSubmit">
                        保存
                    </el-button>
                </div>
            </template>
        </el-dialog>
    </div>
</template>

<style scoped lang="scss"></style>